home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / jed096_1.zip / SLANG / SRC / SLFILE.C < prev    next >
C/C++ Source or Header  |  1994-04-26  |  11KB  |  413 lines

  1. /* file intrinsics for S-Lang */
  2. /* 
  3.  * Copyright (c) 1992, 1994 John E. Davis 
  4.  * All rights reserved.
  5.  *
  6.  * Permission is hereby granted, without written agreement and without
  7.  * license or royalty fees, to use, copy, and distribute this
  8.  * software and its documentation for any purpose, provided that the
  9.  * above copyright notice and the following two paragraphs appear in
  10.  * all copies of this software.
  11.  *
  12.  * IN NO EVENT SHALL JOHN E. DAVIS BE LIABLE TO ANY PARTY FOR DIRECT,
  13.  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
  14.  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOHN E. DAVIS
  15.  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  *
  17.  * JOHN E. DAVIS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
  18.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  19.  * PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
  20.  * BASIS, AND JOHN E. DAVIS HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  21.  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  22.  */
  23.  
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27.  
  28. #if 0
  29. #include <stdio.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <sys/socket.h>
  33. #include <netinet/in.h>
  34. #include <netdb.h>
  35. #include <sys/time.h>
  36. #endif
  37.  
  38. #include "slang.h"
  39. #include "_slang.h"
  40. #include "slfile.h"
  41.  
  42. SL_File_Table_Type SL_File_Table[SL_MAX_FILES];
  43.  
  44.  
  45. #if 0
  46. static int tcp_open (char *service, char *host)
  47. {
  48.    struct servent *sp;
  49.    struct hostent *hp;
  50.    struct sockaddr_in Read_Socket;
  51.    int s;
  52.    
  53.    if (NULL == (sp = getservbyname (service, "tcp")))
  54.      {
  55.     SLang_doerror ("Unknown service");
  56.     return -1;
  57.      }
  58.    
  59.    if (NULL == (hp = gethostbyname(host)))
  60.      {
  61.     SLang_doerror ("Unknown host");
  62.     return -2;
  63.      }
  64.    
  65.    bzero ((char *) &Read_Socket, sizeof (Read_Socket));
  66.    bcopy (hp->h_addr, (char *) &Read_Socket.sin_addr, hp->h_length);
  67.    Read_Socket.sin_family = hp->h_addrtype;
  68.    Read_Socket.sin_port = sp->s_port;
  69.    
  70.    if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  71.      {
  72.     SLang_doerror ("Unable to create socket");
  73.     return -3;
  74.      }
  75.    
  76.    if (connect (s, (char *) &Read_Socket, sizeof (Read_Socket)) < 0)
  77.      {
  78.     SLang_doerror ("Unable to connect.");
  79.     return -4;
  80.      }
  81.    
  82.    return s;
  83. }
  84.  
  85. #endif
  86.  
  87.  
  88.  
  89. SL_File_Table_Type *get_file_table_entry(void)
  90. {
  91.    SL_File_Table_Type *t = SL_File_Table, *tmax;
  92.    
  93.    tmax = t + SL_MAX_FILES;
  94.    while (t < tmax)
  95.      {
  96.     if (t->fd == -1) return t;
  97.     t++;
  98.      }
  99.    
  100.    return NULL;
  101. }
  102.  
  103. static char *remake_string(char *s, int len)
  104. {
  105.    len++;                   /* for null terminator */
  106.    if (s == NULL)
  107.      {
  108.     s = (char *) MALLOC(len);
  109.      }
  110.    else s = (char *) REALLOC(s, len);
  111.    
  112.    if (s == NULL) SLang_Error = SL_MALLOC_ERROR;
  113.    return (s);
  114. }
  115.  
  116.  
  117. unsigned int file_process_flags(char *mode)
  118. {
  119.    char ch;
  120.    unsigned int flags = 0;
  121.    
  122.    while ((ch = *mode++) != 0)
  123.      {
  124.     switch (ch)
  125.       {
  126.        case 'r': flags |= SL_READ; 
  127.          break;
  128.        case 'w':
  129.        case 'a':
  130.        case 'A':
  131.          flags |= SL_WRITE; 
  132.          break;
  133.        case '+': flags |= SL_WRITE | SL_READ; 
  134.          break;
  135.        case 'b': flags |= SL_BINARY; 
  136.          break;
  137.          
  138.        default:
  139.          return(0);
  140.       }
  141.      }
  142.    return (flags);
  143. }
  144.  
  145. /* returns -1 upon failure or returns a handle to file */
  146. int SLfopen(char *file, char *mode)
  147. {
  148.    FILE *fp;
  149.    SL_File_Table_Type *t;
  150.    unsigned int flags;
  151.    
  152.    if ((t = get_file_table_entry()) == NULL) return (-1);
  153.    if (0 == (flags = file_process_flags(mode))) return (-1);
  154.    
  155.    if ((fp = fopen(file, mode)) == NULL) return (-1);
  156.    t->fp = fp;
  157.    t->fd = fileno(fp);
  158.    t->flags = flags;
  159. #ifdef HAS_SUBPROCESSES
  160.    t->pid = -1;
  161. #endif
  162.    return ((int) (t - SL_File_Table));
  163. }
  164.  
  165. #if 0
  166. int SLtcp_open(char *service, char *host)
  167. {
  168.    SL_File_Table_Type *t;
  169.    int fd;
  170.    
  171.    if ((t = get_file_table_entry()) == NULL) return (-1);
  172.    
  173.    if ((fd = tcp_open (service, host)) < 0) return -1;
  174.    t->fp = fdopen (fd, "r+");
  175.    t->fd = fd;
  176.    t->flags = SL_SOCKET | SL_READ | SL_WRITE;
  177.    return ((int) (t - SL_File_Table));
  178. }
  179. #endif
  180.  
  181. /* returns pointer to file entry if it is open and consistent with 
  182.    flags.  Returns NULL otherwise */
  183. static SL_File_Table_Type *check_handle(int *h, unsigned int flags)
  184. {
  185.    int n = *h;
  186.    SL_File_Table_Type *t;
  187.    
  188.    if ((n < 0) || (n >= SL_MAX_FILES)) return(NULL);
  189.    t = SL_File_Table + n;
  190.    if (t->fd == -1) return (NULL);
  191.    if (flags & t->flags) return (t);
  192.    return NULL;
  193. }
  194.  
  195.    
  196.  
  197. /* returns 0 upon failure or 1 if successful */
  198. int SLfclose(int *handle)
  199. {
  200.    int ret = 0;
  201.    
  202.    SL_File_Table_Type *t = check_handle(handle, 0xFFFF);
  203.    
  204.    if (t == NULL) return 0;
  205.    if (t->fp != NULL)
  206.      {
  207.     if (EOF != fclose (t->fp)) ret = 1;
  208.      }
  209. #ifdef USE_SUBPROCESSES
  210.    else if (t->fd != -1)
  211.      {
  212.     if (close (t->fd) == 0) ret = 1; 
  213.      }
  214. #endif
  215.    t->fp = NULL;  t->fd = -1;
  216.    return (ret);
  217. }
  218.  
  219. /* returns number of characters read and pushes the string to the stack.  
  220.    If it fails, it returns -1 */
  221. int SLfgets(int *handle)
  222. {
  223.    char buf[256];
  224.    char *s = NULL, *s1;
  225.    register char *b = buf, *bmax = b + 256;
  226.    register int ch;
  227.    int len = 0, dlen;
  228.    SL_File_Table_Type *t;
  229.    register FILE *fp;
  230.    
  231.  
  232.    if (NULL == (t = check_handle(handle, SL_READ))) return (-1);
  233.    fp = t->fp;
  234.    while (EOF != (ch = getc(fp)))
  235.      {
  236.     if (b == bmax)
  237.       {
  238.          if (NULL == (s1 = remake_string(s, len + 256)))
  239.            {
  240.           if (s != NULL) FREE(s);
  241.           return(-1);
  242.            }
  243.          s = s1;
  244.          b = buf;
  245.          strncpy(s + len, b, 256);
  246.          len += 256;
  247.       }
  248.     *b++ = (char) ch;
  249.     if (ch == '\n') break;
  250.      }
  251.    
  252.    dlen = (int) (b - buf);
  253.    if ((dlen == 0) && (s == NULL)) return(0);
  254.    
  255.    
  256.    if (NULL == (s1 = remake_string(s, len + dlen)))
  257.      {
  258.     if (s != NULL) FREE(s);
  259.     return(-1);
  260.      }
  261.    
  262.    strncpy(s1 + len, buf, dlen);
  263.    len += dlen;
  264.    *(s1 + len) = 0;   /* null terminate since strncpy may not have */
  265.    SLang_push_malloced_string(s1);
  266.    return(len);
  267. }
  268.  
  269. int SLfputs(char *s, int *handle)
  270. {
  271.    SL_File_Table_Type *t;
  272.    
  273.  
  274.    if (NULL == (t = check_handle(handle, SL_WRITE))) return (-1);
  275.    if (EOF == fputs(s, t->fp)) return (0);
  276.    return (1);
  277. }
  278. #if 0
  279. int SLinput_pending(int *handle, int *tsecs)
  280. {
  281.    SL_File_Table_Type *t;
  282.    struct timeval wait;
  283.    fd_set readfd, writefd, exceptfd;
  284.    long usecs, secs;
  285.    int fd, ret;
  286.  
  287.    secs = *tsecs / 10;
  288.    usecs = (*tsecs % 10) * 100000;
  289.    wait.tv_sec = secs;
  290.    wait.tv_usec = usecs;
  291.    
  292.    if (NULL == (t = check_handle(handle, SL_READ))) return (0);
  293.    fd = t->fd;
  294.    if (t->fp->_cnt) return 1;
  295.    
  296.    
  297.    FD_SET(fd, &readfd);   /* readfd = 1 << fd; */
  298.    FD_ZERO(&writefd);
  299.    FD_ZERO(&exceptfd);
  300.  
  301.    ret = select(fd + 1, &readfd, &writefd, &exceptfd, &wait);
  302.    return(ret);
  303.  
  304. }
  305. #endif
  306.  
  307. int SLfflush(int *handle)
  308. {
  309.    SL_File_Table_Type *t;
  310.    
  311.  
  312.    if (NULL == (t = check_handle(handle, SL_WRITE))) return (-1);
  313.    if (EOF == fflush(t->fp)) return (0);
  314.    return (1);
  315. }
  316.  
  317.  
  318.  
  319.  
  320. static int slfile_stdin = 0;
  321. static int slfile_stdout = 1;
  322. static int slfile_stderr = 2;
  323.  
  324. static SLang_Name_Type SLFiles_Name_Table[] = 
  325. {
  326.    MAKE_INTRINSIC(".fopen", SLfopen, INT_TYPE, 2),
  327.    /* Usage: int fopen(String file, String mode);
  328.       Open 'file' in 'mode' returning handle to file.
  329.       Here mode is one of:  "r", "w", "a", "r+", "w+", "a+", "rb", ...
  330.           where 'r' means read, 'w' means write, '+' means read and write,
  331.       'b' means binary, etc...
  332.       Returns -1 if file could not be opened.  Any other value is a handle
  333.       to the file.  This handle must be used in other file operations. */
  334.    MAKE_INTRINSIC(".fclose", SLfclose, INT_TYPE, 1),
  335.    /* Usage: int fclose(int handle);
  336.       Closes file associated with 'handle'.  
  337.       returns: 0 if file could not be closed or buffers could not be flushed.
  338.                1 upon success.
  339.            -1 if handle is not associated with an open stream. */
  340.    MAKE_INTRINSIC(".fgets", SLfgets, INT_TYPE, 1),
  341.    /*  Usage:  [String]